// detect
/*
 * Things to remember:
 * 1. Binary Search? DP? Greedy? Bitset?
 * 2. Find a conclusion?
 * 3. long long? Enough array size?
 * 4. Stay calm and focus on main points!
 * 5. CLEAR IN MULTI_TEST!!!
 * */
#include <cstdio>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i, s, t) for(int i=s; i<=t; ++i)
#define debug(x) cerr<<#x<<":"<<x<<"\n";
using namespace std;
const int N=1000010;

int n, m, L, V;
struct node
{
	int l, r;
} b[N]; int cnt;
int sum[N];
bool cmp1(node a, node b)
{
	if(a.l!=b.l) return a.l>b.l;
	return a.r<b.r;
}
bool cmp2(node a, node b)
{
	if(a.l!=b.l) return a.l<b.l;
	return a.r<b.r;
}

void solve()
{
	scanf("%d%d%d%d", &n, &m, &L, &V);
	rep(i, 1, n)
	{
		int d, v, a; scanf("%d%d%d", &d, &v, &a);
		if(a==0)
		{
			if(v>V)
			{
				b[++cnt]={d, L};
			}
			continue;
		}
		if(a>0)
		{
			int l=d, r=L, res=-1;
			while(l<=r)
			{
				int mid=l+r>>1, s=mid-d;
				if(v*v+2*a*s>V*V)
					res=mid, r=mid-1;
				else l=mid+1;
			}
			if(~res)
			{
				b[++cnt]={res, L};
			}
		}
		else
		{
			int l=d, r=L, res=-1;
			while(l<=r)
			{
				int mid=l+r>>1, s=mid-d;
				if(v*v+2*a*s>V*V)
					res=mid, l=mid+1;
				else r=mid-1;
			}
			if(~res)
			{
				b[++cnt]={d, res};
			}
		}
	}
	rep(i, 1, m)
	{
		int x; scanf("%d", &x);
		sum[x]=1;
	}
	rep(i, 1, L) sum[i]+=sum[i-1];
	int res1=0;
	rep(i, 1, cnt)
	{
		int l=b[i].l, r=b[i].r;
		if(sum[r]-(l?sum[l-1]:0)>0)
			b[++res1]=b[i];
	}
	printf("%d ", res1);
	sort(b+1, b+res1+1, cmp1);
	int cc=0, mnr=1e9;
	rep(i, 1, res1)
	{
		if(b[i].r<mnr) b[++cc]=b[i], mnr=b[i].r;
	}
	sort(b+1, b+cc+1, cmp2);
	int lastr=-1, res2=0;
	rep(i, 1, cc)
	{
		int l=b[i].l, r=b[i].r;
		if(l<=lastr && sum[lastr]-(l?sum[l-1]:0)>0)
			;
		else
		{
			lastr=b[i].r;
			res2++;
		}
	}
	printf("%d\n", m-res2);
	cnt=0; rep(i, 0, L) sum[i]=0;
}

int main()
{
	freopen("detect.in", "r", stdin);
	freopen("detect.out", "w", stdout);
	int T; scanf("%d", &T);
	while(T--) solve();
	
	return 0;
}